home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Info 1994 March
/
Internet Info CD-ROM (Walnut Creek) (March 1994).iso
/
networking
/
mail
/
mh
/
contrib
/
jpeek
/
mail.sort
< prev
next >
Wrap
Text File
|
1992-08-08
|
7KB
|
220 lines
#! /bin/sh
# $Header: /home/jerry/.bin/RCS/mail.sort,v 3.6 92/08/09 23:26:31 jerry mh_contrib $
### mail.sort - sort mail messages in place, or link to temporary folder
### Usage: mail.sort [folder] [-verbose] [-help] [-link [msgs]] [-c|f|o|s|t|x]"
##
## THE sortm(1) PROGRAM FROM MH 6.6 CAN SORT MAIL MESSAGES BY
## DATE. BUT IF YOU WANT TO GROUP ORIGINAL MESSAGES WITH THEIR
## REPLIES, OR SORT BY THE PERSON WHO SENT THEM, YOU CAN USE THIS
## SCRIPT. (THE MH 6.7 sortm IS MORE POWERFUL--AND IT DOES A LOT,
## BUT NOT ALL, OF WHAT mail.sort DOES.)
##
## mail.sort CAN SORT BY SUBJECT, IGNORING THE Re: SO THAT REPLIES
## ARE GROUPED WITH THE ORIGINAL MESSAGE. IT CAN SORT BY THE
## Sender:, IF THERE IS ONE-- OTHERWISE, BY THE From:. THERE ARE 6
## OTHER WAYS TO SORT, AS WELL.
##
## mail.sort USES scan FORMAT STRINGS TO PULL HEADER INFORMATION
## OUT OF EACH MESSAGE. SO, IF YOU CAN WRITE A FORMAT STRING, YOU
## CAN SORT BY IT. IF THERE'S A FORMAT STRING THAT YOU USE A LOT,
## YOU CAN ADD A NEW OPTION TO mail.sort (BY ADDING A SINGLE LINE
## OF CODE) THAT LETS YOU USE THAT FORMAT STRING ANY TIME, JUST BY
## TYPING YOUR NEW OPTION ON THE COMMAND LINE.
##
## BY DEFAULT, mail.sort SORTS MESSAGES AND PUTS THEM BACK IN THE
## SAME FOLDER. IT CAN ALSO LINK ALL THE MESSAGES INTO A TEMPORARY
## SUB-FOLDER WITHOUT CHANGING THE SOURCE FOLDER ORDER. WHEN
## YOU'RE DONE WITH THE SUB-FOLDER, YOU CAN REMOVE IT.
##
## THE -v OPTION WRITES VERBOSE INFO ABOUT WHAT'S HAPPENING TO stdout.
#
# NOTE TO HACKERS: TABSTOPS SET AT 4 IN THIS CODE
#
# USE AT YOUR OWN RISK. SEEMS TO WORK, BUT IT'S YOUR RESPONSIBILITY!
# PLEASE TELL ME ABOUT BUGS AND FIXES: Jerry Peek, jerry@ora.com
umask 77 # PROTECT TEMPORARY FILE
folopts="-nolist -nototal" # OVERRIDE MH PROFILE
mh=/usr/local/mh # WHERE MH COMMANDS LIVE
myname="`basename $0`" # THIS PROGRAM'S NAME
scanopts="-width 200 -noclear -noheader -noreverse" # OVERRIDE MH PROFILE
stat=1 # DEFAULT EXIT STATUS; RESET TO 0 BEFORE NORMAL exit
subfol=MAILSORT$$ # TEMPORARY SUB-FOLDER
temp=/tmp/MSORT$$
usage="Usage: $myname [folder] [-verbose] [-help] [-link [msgs]] [-c|f|o|s|t|x]"
# trapS COME LATER... SEE BELOW.
what=/bin/mv # DEFAULT IF NO -link
for arg
do
case "$arg" in
[+@]*) folder="$arg" ;;
-h*) echo "$usage
Replaces messages in same folder unless you use -link,
when messages are linked into a sorted sub-folder.
Sorts by Subject with Re:'s stripped,
unless you use one of the following:
-f[rom]
-s[ender]
-o[rigin] (Sender, otherwise From)
-t[o]
-c[c]
-r[eply-to]
-x (exact Subject, including Re:'s)
$myname, \$Revision: 3.6 $ \$Date: 92/08/09 23:26:31 $"
stat=0
exit
;;
-l*) what=/bin/ln ;;
-v*) vflag=y ;;
-*) # SET COMPONENT TO SORT ON:
case "$how" in
?*) echo "$myname: '$arg'? Only one of -c, -f, -o, -s, -t, -x." 1>&2
exit
;;
esac
# NO DATE SORT HERE BECAUSE sortm DOES THAT, AND FASTER...
case "$arg" in
-f*) how='%(mbox{from})' ;; # FROM (mbox)
-s*) how='%(mbox{sender})' ;; # SENDER (mbox)
-t*) how='%(mbox{to})' ;; # TO (IGNORE MUTIPLE ADDRESSES)
-c*) how='%(mbox{cc})' ;; # CC (IGNORE MUTIPLE ADDRESSES)
-r*) how='%(mbox{reply-to})' ;; # REPLY-TO (mbox)
-x*) how='%{subject})' ;; # EXACT SUBJECT (INCLUDE Re:)
-o*) # SORT BY Sender, IF THERE IS ONE, OTHERWISE BY From:
how='%<{sender}%(mbox{sender})%|%(mbox{from})%>'
;;
*) echo "$usage
(invalid switch '$arg')" 1>&2
exit
;;
esac
;;
*) # ONLY ALLOW MESSAGE ARGUMENTS IF LINKING; CAN RUIN FOLDER OTHERWISE:
case "$what" in
*ln) msgargs="$msgargs $arg" ;;
*) echo "$usage
('$arg'? No message numbers unless using -link.)" 1>&2
exit 1
;;
esac
;;
esac
done
origfol="`$mh/folder $folopts $folder -fast`"
cd `$mh/mhpath +$origfol` || exit
# SET trapS THAT TELL USER HOW TO RECOVER WHEN stat != 1:
trap 'echo "$myname: Interrupted." 1>&2' 1 2 15
case "$what" in
*ln) # SPECIAL MESSAGE FOR LINKING:
trap 'case "$stat" in 1) echo "$myname: You should run:
rmf +$origfol/$subfol" 1>&2;; esac;
rm -f $temp; exit $stat' 0
;;
*) trap 'case "$stat" in 1) echo "$myname: Recover with:
folder +$origfol/$subfol
refile all @..
folder (be sure +$origfol/$subfol is empty)
rmf (remove +$origfol/$subfol)" 1>&2;; esac' 0
;;
esac
mkdir $subfol || exit
exec 3>&2 # SAVE ORIGINAL stderr; WE RESTORE IT LATER
exec 2>$temp # THROW stderr MESSAGES INTO $temp; TEST AT END OF THIS MESS
case "$vflag" in
y) echo "$myname: sorting messages to temporary folder..." ;;
esac
# START LONG PIPELINE TO GET LIST OF MESSAGES, WITH OLD AND NEW NUMBERS.
# SPIT MESSAGE NUMBERS AND TEXT FIELD TO STANDARD OUTPUT OF case.
case "$how" in
"") # SORT BY SUBJECT (DEFAULT); STRIP OFF "Re:", "RE:", "Re: Re:", ETC:
$mh/scan $scanopts -format '%(msg)#%{subject}' $msgargs |
sed -n '
/^[1-9][0-9]*#[Rr][Ee]:/ {
:rezap
s/^\([1-9][0-9]*#\)[Rr][Ee]: */\1/
/^[1-9][0-9]*#[Rr][Ee]:/b rezap
}
p'
;;
*) # SORT BY WHATEVER ELSE (FORMAT STRING IS IN $how):
$mh/scan $scanopts -format "%(msg)#$how" $msgargs
;;
esac |
sort -t\# +1 | # SORT BY TEXT FIELD
awk '{ kut = index($0, "#") # ADD NEW MESSAGE NUMBERS, REMOVE "#"
print NR, substr($0, 1, kut-1), substr($0, kut+1) }' |
while read new old text
do
# MOVE OR LINK MESSAGES INTO SUB-FOLDER, ONE BY ONE.
#
# IF MESSAGE WAS UNREADABLE, scan PRINTED A LINE (TO STANDARD
# OUTPUT!) LIKE THIS, WITH LEADING BLANKS UNLESS msgnum > 999:
# <msgnum> unreadable
# WE GET THAT WITH A LINE NUMBER IN FRONT FROM awk...
# IF THERE ARE LEADING BLANKS, SOME BOURNE SHELLS WILL COPY ALL
# THIS STUFF INTO $text, AND LEAVE BOTH $new AND $old
# EMPTY. TRY TO CATCH BOTH CASES:
case "$new" in
"") echo "$myname: message $new $old $text" 1>&2; break ;;
esac
case "$text" in
unreadable) echo "$myname: can't read msg '$old'???" 1>&2; break ;;
esac
# USE UNIX COMMANDS; AVOID ALL THE OVERHEAD THAT refile WOULD ADD:
if $what $old $subfol/$new
then
case "$vflag" in
y) echo "$myname: old #$old --> new #$new ($text)" ;;
esac
else
echo "$myname: '$what $old $subfol/$new' failed." 1>&2
break
fi
done
exec 2>&- # CLOSE TEMPORARY stderr
exec 2>&3 # RESTORE ORIGINAL stderr
# IF THERE WERE ANY ERRORS IN THE MESS ABOVE, SHOW THEM AND EXIT:
if test -s $temp
then
echo "$myname: quitting:" 1>&2
cat $temp 1>&2
exit
fi
set -e # exit IF ANY ERROR FROM NOW ON
case "$what" in
*ln)
case "$vflag" in
y) $mh/folder @$subfol
echo "$myname: done."
echo "When you're done with this sub-folder, type 'rmf' to remove it."
;;
*) $mh/folder -fast @$subfol >/dev/null ;;
esac
;;
*)
# cd TO SUB-FOLDER AVOIDS LONG PATHNAMES (& COMMAND LINE OVERFLOW):
cd $subfol
case "$vflag" in
y) echo "$myname: moving messages back to original folder..." ;;
esac
/bin/mv * ..
cd ..
/bin/rmdir $subfol
;;
esac
stat=0
exit